package com.tckdq.tcc.service.impl;

import com.tckdq.tcc.domain.SmsCodeDto;
import com.tckdq.tcc.dto.SMSVerifiy2RedisDto;
import com.tckdq.tcc.enums.ErrorCodeEnum;
import com.tckdq.tcc.exception.BusinessException;
import com.tckdq.tcc.exception.GlobalException;
import com.tckdq.tcc.service.IMessageSmsService;
import com.tckdq.tcc.service.iVerifyCodeService;
import com.tckdq.tcc.utils.StrUtils;
import com.tckdq.tcc.utils.VerifyCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeServiceImpl implements iVerifyCodeService {



    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private IMessageSmsService messageSmsService;
    @Override
    public String getImgCode(String key) throws IOException {
        //获取图片验证码
        String code = StrUtils.getComplexRandomString(4);

        //把验证码放在redis,设置验证码的失效
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);

        //把验证码的值合并到图片,使用base64编码,返回String字符串
        String verifyCode = VerifyCodeUtils.verifyCode(115, 40, code);
        return verifyCode;
    }

    /*手机验证码*/
    @Override
    public void smsCode(SmsCodeDto smsCodeDto) {
//1.校验 - 空值校验
        String phone = smsCodeDto.getMobile();
        String imageCode = smsCodeDto.getImageCode();
        String imageCodeKey = smsCodeDto.getImageCodeKey();
        if(StringUtils.isEmpty(phone)){
            throw new BusinessException(ErrorCodeEnum.TELNUM_ERROR);
        }
        if(StringUtils.isEmpty(imageCode)){
            throw new BusinessException(ErrorCodeEnum.REFRESH);
        }
        if(StringUtils.isEmpty(imageCodeKey)){
            throw new BusinessException(ErrorCodeEnum.IMG_ERROR);
        }

        if (redisTemplate.opsForValue().get("blacklist"+phone) != null){
            throw new GlobalException("您已经被禁⽤发送短信验证码，请联系管理员",null);
        }
        //2.校验 - 图片验证码校验
        //2.1.图片验证码是否过期
        Object imageCodeKeyVal = redisTemplate.opsForValue().get(imageCodeKey);
        if (imageCodeKeyVal==null){
            throw new BusinessException(ErrorCodeEnum.IOBSOLETE_ERROR);
        }
        //2.2图片验证码和输入的验证码是否一致
        if(!imageCodeKeyVal.toString().equalsIgnoreCase(imageCode)){
            throw new BusinessException(ErrorCodeEnum.ATYPISM_ERROR);
        }

        //生成手机验证码
        //redis存值格式：key[register:18708146200] : value[code:time]
        //1.从redis获取验证码,并判断
        SMSVerifiy2RedisDto redisDto = (SMSVerifiy2RedisDto)redisTemplate.opsForValue().get("register:" + phone);
        //验证码设置为null
        String smscode =null;
        //2.判断
        if(redisDto==null){
            //若redis没有验证码,则第一次获取验证码,或者验证码过期,就重新创建验证码
            smscode =StrUtils.getRandomString(6);
        }else {
            Long currentTime = System.currentTimeMillis();
            //String oldtime = redisDto.toString().split(":")[1];
            Long oldtime = redisDto.getTime();
            if(oldtime-currentTime<=1*60*1000){
                throw new BusinessException(ErrorCodeEnum.REPEAT_ERROR);
            }else {
                //使用以前的验证码
                smscode = redisDto.getCode();
            }
        }

        //3手机验证码保存redis
        SMSVerifiy2RedisDto redisDtoSet = new SMSVerifiy2RedisDto();
        Date date = new Date();
        long time = date.getTime();
        redisDtoSet.setTime(time);
        redisDtoSet.setCode(smscode);
        redisTemplate.opsForValue().set("register:" + phone,redisDtoSet,3,TimeUnit.MINUTES);

        //发送验证码
        /*iVerifyCodeService.smsCode(smsCodeDto);*/
        String conde ="你的验证码为：" + smscode + "，请在3分钟之内使用!";
        log.info(conde);

        messageSmsService.save(phone,conde);

    }

}
